#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
主题: 增加或改变已打开文件的编码
问题: 你想在不关闭一个已打开的文件前提下增加或改变它的Unicode编码。
提示 :
"""

import urllib.request
import io
import sys

def recipe1():
    u = urllib.request.urlopen('http://www.python.org')
    f = io.TextIOWrapper(u, encoding='utf-8')
    print(f"{f.read() = }")

def recipe2():
    print(f"{sys.stdout.encoding = }")
    sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='latin-1')
    print(f"{sys.stdout.encoding = }")

def recipe3():
    f = open('16_change_opencode_1.txt', 'w')
    print(f"{f = }")            # 编码和解码Unicode的文本处理层
    print(f"{f.buffer = }")     # 处理二进制数据的带缓冲的I/O层
    print(f"{f.buffer.raw = }") # 表示操作系统底层文件描述符的原始文件
    f.write('Hello')

    f = io.TextIOWrapper(f.buffer, encoding='latin-1')
    print(f"{f = }")
    # f.write('Hello')      # ValueError: I/O operation on closed file.

def recipe4():
    f = open('16_change_opencode_2.txt', 'w')
    print(f"{f = }")
    b = f.detach()          # 断开文件的最顶层并返回第二层
    print(f"{b = }")
    # f.write('Hello')      # ValueError: I/O operation on closed file.

    # 添加一个新的最顶层
    f = io.TextIOWrapper(b, encoding='latin-1')
    print(f"{f = }")

def recipe5():
    '''
    改变文件行处理、错误机制以及文件处理的其他方面
    '''
    sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='ascii', errors='xmlcharrefreplace')
    print('Jalape\u00f1o')
    print('张三')

def main():
    print('recipe1'.center(20, '*'))
    recipe1()
    print('recipe2'.center(20, '*'))
    recipe2()
    print('recipe3'.center(20, '*'))
    recipe3()
    print('recipe4'.center(20, '*'))
    recipe4()
    print('recipe5'.center(20, '*'))
    recipe5()

if __name__ == '__main__':
    main() 